#pragma once
#include <iostream>
#include <unordered_map>
#include "Protocol.hpp"
#include "../Connection.hpp"
#include "Request&&Response.hpp"
#include "../RoomPlayers.hpp"

// 玩家准备时的请求以及响应格式
// 请求报文中会表明这是一个玩家准备的报文
// Request: CreateRoom -> $len${ "server_type" : "QuitRoom"}
// 响应会处理请求报文，本地直接退出即可

extern std::unordered_map<std::string, Room *> rooms;
extern std::unordered_map<int, std::string> fd_to_room_number;

class RequestPlayMove : public Request
{
public:
    RequestPlayMove() {}

    virtual bool Serialize(std::string *msg)
    {
        // Json::Value root;
        // root["server_type"] = PlayerMove;
        // root["player_id"] = player_id;
        // root["player_to_right"] = _player_to_right;
        // root["player_to_left"] = _player_to_left;
        // root["player_to_up"] = _player_to_up;
        // root["player_to_down"] = _player_to_down;
        // //root["room_number"] = _room_number;
        // Json::FastWriter writer;
        // *msg = writer.write(root);

        return true;
    }
    virtual bool Deserialize(const Json::Value &root)
    {
        // std::cout << "msg right: " << _player_to_right << std::endl;
        _player_id = root["player_id"].asInt();
        _player_to_right = root["player_to_right"].asBool();
        _player_to_left = root["player_to_left"].asBool();
        _player_to_up = root["player_to_up"].asBool();
        _player_to_down = root["player_to_down"].asBool();
        // std::cout << "req right: " << root["player_to_right"].asBool() << std::endl;
        return true;
    }

    void SetMove(bool player_to_right, bool player_to_left, bool player_to_up, bool player_to_down)
    {
        _player_to_right = player_to_right;
        _player_to_left = player_to_left;
        _player_to_up = player_to_up;
        _player_to_down = player_to_down;
    }

    void Reset()
    {
        _player_to_right = false, _player_to_left = false, _player_to_up = false, _player_to_down = false;
    }

    ~RequestPlayMove() {}

public:
    int _player_id = 0;
    bool _player_to_right = false, _player_to_left = false, _player_to_up = false, _player_to_down = false;
};

class ResponsePlayMove : public Response
{
public:
    ResponsePlayMove() {}

    virtual bool Serialize(std::string *msg)
    {
        return true;
    }

    // 收到客户端发来的退出的请求时，服务器端需要向处在房间的其他人发送退出房间信号
    bool ServerHandler(RequestPlayMove *req, Connection *conn)
    {
        std::vector<Player> &players = rooms[fd_to_room_number[conn->GetFd()]]->GetPlayers();
        std::string msg;
        Json::Value root;
        root["server_type"] = PlayerMove;
        root["player_id"] = req->_player_id;


        // 同步到本地的玩家状态

        double x = 0, y = 0;
        if (req->_player_to_left)
            x -= player_speed;
        if (req->_player_to_right)
            x += player_speed;
        if (req->_player_to_up)
            y -= player_speed;
        if (req->_player_to_down)
            y += player_speed;
        // 解决斜向运动速度过快的问题

        req->Reset();

        if (x && y)
        {
            x = (x * sqrt(2)) / 2;
            y = (y * sqrt(2)) / 2;
        }
        // std::cout << "peer_player_id: " << peer_player_id << " " << " x: " << x << " y: " << y << std::endl;
        players[req->_player_id].Move(x, y);

        // std::cout << "req right: " << req->_player_to_right << std::endl;
        root["player_to_right"] = req->_player_to_right;
        root["player_to_left"] = req->_player_to_left;
        root["player_to_up"] = req->_player_to_up;
        root["player_to_down"] = req->_player_to_down;
        root["x"] = players[req->_player_id]._x;
        root["y"] = players[req->_player_id]._y;
        // std::cout << "resp right: " << root["player_to_right"].asBool() << std::endl;

        Json::FastWriter writer;
        msg = writer.write(root);
        // std::cout << "play move msg: " << msg;
        Package(msg, &msg);
        for (int i = 0; i < players.size(); i++)
        {
            if (players[i].Exist())
            {
                Connection *conn_player = players[i].GetConnection();
                // if (conn != conn_player)
                // {
                conn_player->GetOutbuffer() += msg;
                // std::cout << "conn_player->GetOutbuffer() " << conn_player->GetOutbuffer() << std::endl;
                conn_player->GetWriter()(conn_player);
                // }
            }
        }

        return true;
    }

    virtual bool Deserialize(const std::string &result)
    {
        // Json::Value root;
        // Json::Reader reader;
        // reader.parse(result, root);

        // _player_id = root["player_id"].asInt();
        // _player_to_right = root["player_to_right"].asBool();
        // _player_to_left = root["player_to_left"].asBool();
        // _player_to_up = root["player_to_up"].asBool();
        // _player_to_down = root["player_to_down"].asBool();

        return true;
    }

    virtual ~ResponsePlayMove() {}
    bool _player_to_right = false, _player_to_left = false, _player_to_up = false, _player_to_down = false;

private:
    int _player_id = -1;
};